//
//  WBStatusListModel.swift
//  SainMicroblog
//
//  Created by chenxinju on 16/5/6.
//  Copyright © 2016年 chenxinju-a2. All rights reserved.
//

import UIKit
import SDWebImage

class WBStatusListModel: NSObject {
    
    ///  viewModel要做的事
    ///1.请求网络
    ///2.需要和model进行关联
    // 3.保存数据到SQL中
    
    
    //定义viewModel单例
    static let shareInstance: WBStatusListModel = WBStatusListModel()
    
    //懒加载数组 (WBStatusViewModel类是关联数据类)
    lazy var statusList:[WBStatusViewModel] = [WBStatusViewModel]()
    
     //数据获取逻辑
    func loadData(since_id: Int = 0,max_id: Int = 0, sccess:(count:Int)->(),failed:(error:NSError)->()){
     //1.思路 不管有没有网 先展示数据库的数据
     //2. 当用户去下拉刷新时 去数据库看看有没有满足的数据 如果有满足的数据,直接返回; 如果没有 去网络加载
        
      readDB(max_id, since_id: since_id) { (data) -> () in
        
        //1.定义一个临时数组
        var tamp = [WBStatusViewModel]()
        if data.count > 0 {  //数据库有数据直接展示数据
      
        //2.对数组进行遍历
            for status in data {
          //3. 字典转模型
            let model = WBStatus(dic: status)
            
           let statusViewModel = WBStatusViewModel(model: model)
            //数组添加数据
         tamp.append(statusViewModel)
            
            }
            
            
            if max_id > 0 { //进行拼接数组数据
                
                self.statusList = self.statusList + tamp
                
            }else {
                //第一次的时候的数据
                self.statusList = tamp + self.statusList
            }
            //回调
            sccess(count: -1)
        } else {  //请求网络数据
        
      self.NetloadData(since_id, max_id: max_id, sccess: sccess, failed: failed)
        
        }
    
      }
    
    }
    //网络加载数据
    func NetloadData(since_id: Int = 0,max_id: Int = 0, sccess:(count:Int)->(),failed:(error:NSError)->()){
      
        let url = "https://api.weibo.com/2/statuses/home_timeline.json"

        //如果token值为空 直接返回
        guard let token = WBOauthViewModel.shareInstance.access_token else {
            return
        }
        
        /*
        access_token	true	string	采用OAuth授权方式为必填参数，OAuth授权后获得。
        since_id	false	int64	若指定此参数，则返回ID比since_id大的微博（即比since_id时间晚的微博），默认为0。
        max_id	false	int64	若指定此参数，则返回ID小于或等于max_id的微博，默认为0。
        count	false	int	单页返回的记录条数，最大不超过100，默认为20。
        */
        
        let params:[String : AnyObject] = ["access_token":token,
            "since_id": since_id,
            "max_id": max_id,
            "count":50
        ]
        
        //发送请求
        WBHTTPClient.shareInstance.request(.GET, URLString: url, parameters: params, success: { (_ , JSON) -> Void in
            
            //定义一个队列组
            let group = dispatch_group_create()
            var count = 0
            //print(JSON)
            //需要对数据进行解析
            if let json = JSON as? [String:AnyObject] {
                
                //1.先拿到status 里面是一个数组
                if let status = json["statuses"] as? [[String:AnyObject]] {
                    
                    //**********调用数据库保存
                  self.saveDB(status)
                    
                    
                    //定义一个临时数组 来缓存图片数据
                    var tamp = [WBStatusViewModel]()
                    
                    //一个可选的数据 不能进行遍历
                    //2.对数组进行遍历
                    for status in status {
                        
                        //3.字典转模型
                        let model = WBStatus(dic: status)
                        //给ViewModel属性赋值
                        let statusViewModel = WBStatusViewModel(model: model)
                        
                       // print(statusViewModel.status?.id)
                        
                        //判断下载的图片是否是一张
                        //只有一张的时候需要去下载图片
    if let pic_urls = statusViewModel.retweet_pic_urls == nil ? statusViewModel.status?.pic_urls: statusViewModel.retweet_pic_urls where pic_urls.count == 1 {
                            
                            //添加组队列
                            dispatch_group_enter(group)
                            
                            //下载图片有系统和借助第三方
        SDWebImageManager.sharedManager().downloadImageWithURL(pic_urls.first?.thumbnail_pic, options: [], progress: nil, completed: { (image, _ , _, _ , _) -> Void in
                                
//                                //下载完成的回调
//                                let data = UIImagePNGRepresentation(image)
//                                 print(data)
                                
                    dispatch_group_leave(group) //队列出组
                                
                            })
                            
                        }
                        // 添加临时数据
                        tamp.append(statusViewModel)
                        
                    }
                    if max_id > 0 {
                        //数组添加数据 对临时数据进行拼接
                        self.statusList = self.statusList + tamp
                        
                    }else {
                        //第一次的时候的数据
                        self.statusList = tamp + self.statusList
                    }
                   count = tamp.count
                }
                
            }
            
            //每组下载都是异步 线程完成之后再回调控制器
            dispatch_group_notify(group, dispatch_get_main_queue(), { () -> Void in
                //解析完之后告诉控制器刷新数据
                sccess(count: count)
            })
            
            
            }) { (_ , error) -> Void in
                printLog(error)
                //处理错误
                failed(error: error)
        }
    }
    
    //MARK: - 数据库保存数据的方法
    private func  saveDB(array: [[String: AnyObject]]) {
    //1. 拼接sql 语句
        let sql = "INSERT OR REPLACE INTO T_Status (status_id,status,user_id) VALUES (?,?,?);"
     //把数组传进来 进行遍历
        for info in array {
        //2.去组装参数
     let statusid = info["id"] as! Int
    //2.1 字典转data
     let data = try! NSJSONSerialization.dataWithJSONObject(info, options: [])
    
      //2.2 data转换为字符串 
     let status = String(data: data, encoding: NSUTF8StringEncoding)!
            
      //3. 保存到数据里 注意一定要对的数据进行解包 不然保存到数据中 会有报Optional错误(空)
      let userid = WBOauthViewModel.shareInstance.access_token!
     
    //调用数据库的方法 去保存数据
      WBDBManager.shareInstance.queue.inDatabase({ (db) -> Void in
        
        if db.executeUpdate(sql, withArgumentsInArray: [statusid,status,userid]) {
        
           print("插入数据库成功")
        }else {
           print("插入数据库失败")
        }
   
      })
            
    }
    
  }
    
    //MARK: - 读取数据的方法
    private func readDB(max_id:Int,since_id:Int,finish:(data: [[String:AnyObject]]) ->()) {
     let userid = WBOauthViewModel.shareInstance.access_token!
        
    var sql = "SELECT status FROM T_Status WHERE user_id = '\(userid)' AND\n"
        if  max_id > 0 {
         //上拉
        sql = sql + "status_id < \(max_id)\n"
        
        }else {
         //下拉刷新
         sql = sql + "status_id > \(since_id)\n"
        
        }

       //数据进行排序 LIMIT也要放到最后
        sql = sql + " ORDER BY status_id DESC LIMIT 20 ;\n"
    
       //2.初始化一个临时数据
        var tamp: [[String:AnyObject]] = [[String:AnyObject]]()
        
        //请求数据库
        WBDBManager.shareInstance.queue.inDatabase { (db) -> Void in
        let rs = db.executeQuery(sql, withArgumentsInArray: nil)
        
            while rs.next() {
            //读取的时候需要把String转换成 Data 再把Data转成字典 
            let status = rs.stringForColumn("status")
            
            //把string转成data  需要进行OC转换
            let data = (status as NSString).dataUsingEncoding(NSUTF8StringEncoding)!
            //把data 转换为字典
        let dic = try! NSJSONSerialization.JSONObjectWithData(data, options: []) as! [String:AnyObject]
                
        //把字典拼接到数组
        tamp.append(dic)
            
            }
        }
        
        finish(data: tamp) //返回
    }
    
    
    //MARK: - 删除数据库过期时间的数据
     func deleData() {
    //   -- 数据库比较时间是通过字符串来比较的
    //  DELETE FROM T_Status WHERE createDate < '2016-05-19 15:30:45';
   let dateformmate = NSDateFormatter()
        
        dateformmate.dateFormat = "yyyy-MM-dd HH:mm:ss"
        //时区
        dateformmate.locale = NSLocale(localeIdentifier: "en_US")
        
        //前一天的时间 -24*60*60
        let date = NSDate(timeIntervalSinceNow: -1*60)
        
        
        let dateStr = dateformmate.stringFromDate(date)
        
//         print(dateStr)
        //拼接sql语句
        let sql = "DELETE FROM T_Status WHERE createDate < ?;"
        //执行sql
        WBDBManager.shareInstance.queue.inDatabase { (db) -> Void in
            db.executeUpdate(sql, withArgumentsInArray: [dateStr])
        }
    }
}
